package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.annotation.AutoFill;
import com.sky.constant.MessageConstant;
import com.sky.constant.PasswordConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.entity.Employee;
import com.sky.enumeration.OperationType;
import com.sky.exception.AccountLockedException;
import com.sky.exception.AccountNotFoundException;
import com.sky.exception.PasswordErrorException;
import com.sky.mapper.EmployeeMapper;
import com.sky.result.PageResult;
import com.sky.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;

@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 员工登录
     *
     * @param employeeLoginDTO
     * @return
     */
    public Employee login(EmployeeLoginDTO employeeLoginDTO) {
        String username = employeeLoginDTO.getUsername();
        String password = employeeLoginDTO.getPassword();

        //1、根据用户名查询数据库中的数据
        Employee employee = employeeMapper.getByUsername(username);

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (employee == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对
        // TODO 后期需要进行md5加密，然后再进行比对

        password = DigestUtils.md5DigestAsHex(password.getBytes());

        String employeePassword = employee.getPassword();//数据库的密码
        //去除数据库密码中\n
        employeePassword = employeePassword.replace("\n", "");
        if (!password.equals(employeePassword)) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        if (employee.getStatus() == StatusConstant.DISABLE) {
            //账号被锁定
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //3、返回实体对象
        return employee;
    }

    @Override
    @AutoFill(value = OperationType.INSERT)//自动填充创建时间和修改时间等字段
    public void MySave(EmployeeDTO employeeDTO) {
        //新增员工信息po
        Employee employee = new Employee();
        //将po转换成dto
        BeanUtil.copyProperties(employeeDTO, employee);
        //密码加密处理 默认是123456
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
        employee.setStatus(StatusConstant.ENABLE);
        //设置当前记录的创建人的id和修改人的id
        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());
        this.save(employee);

    }

    @Override
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        //1.获取当前页码和每页显示的条数
        int page = employeePageQueryDTO.getPage();
        int pageSize = employeePageQueryDTO.getPageSize();
        //2.创建分页对象
        Page<Employee> p = new Page<>(page, pageSize);
        //3.构造条件
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(employeePageQueryDTO.getName() != null && !employeePageQueryDTO.getName().isEmpty(), Employee::getName, employeePageQueryDTO.getName());
        //加上排序时间
        wrapper.orderByDesc(Employee::getCreateTime);
        //4.进行分页查询
        this.page(p, wrapper);
        // 5. 返回分页结果
        return new PageResult(p.getTotal(), p.getRecords());

    }

    @AutoFill(value = OperationType.UPDATE)//自动填充修改时间等字段
    @Override
    public void startOrStop(Long id, Integer status) {
        Employee employee = Employee.builder().id(id).status(status).build();
        //手动更新时间
        employee.setUpdateTime(new Date());
        LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Employee::getId, employee.getId())
                .set(employee.getName() != null && !employee.getName().isEmpty(), Employee::getName, employee.getName())
                .set(employee.getPhone() != null && !employee.getPhone().isEmpty(), Employee::getPhone, employee.getPhone())
                .set(employee.getSex() != null && !employee.getSex().isEmpty(), Employee::getSex, employee.getSex())
                .set(employee.getIdNumber() != null && !employee.getIdNumber().isEmpty(), Employee::getIdNumber, employee.getIdNumber())
                .set(employee.getUsername() != null && !employee.getUsername().isEmpty(), Employee::getUsername, employee.getUsername())
                .set(employee.getStatus() != null, Employee::getStatus, employee.getStatus())
                .set(employee.getUpdateTime() != null, Employee::getUpdateTime, employee.getUpdateTime())
                .set(employee.getUpdateUser() != null, Employee::getUpdateUser, employee.getUpdateUser());
        this.update(wrapper);



    }

    @AutoFill(value = OperationType.UPDATE)//自动填充修改时间等字段
    @Override
    public void updateEmployee(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        //将dto转换成po
        BeanUtil.copyProperties(employeeDTO, employee);
        //设置当前记录的修改人的id
        employee.setUpdateUser(BaseContext.getCurrentId());
        //设置密码
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));

        //手动更新时间
        employee.setUpdateTime(new Date());
        LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Employee::getId, employee.getId())
                .set(employee.getName() != null && !employee.getName().isEmpty(), Employee::getName, employee.getName())
                .set(employee.getPhone() != null && !employee.getPhone().isEmpty(), Employee::getPhone, employee.getPhone())
                .set(employee.getSex() != null && !employee.getSex().isEmpty(), Employee::getSex, employee.getSex())
                .set(employee.getIdNumber() != null && !employee.getIdNumber().isEmpty(), Employee::getIdNumber, employee.getIdNumber())
                .set(employee.getUsername() != null && !employee.getUsername().isEmpty(), Employee::getUsername, employee.getUsername())
                .set(employee.getStatus() != null, Employee::getStatus, employee.getStatus())
                .set(employee.getUpdateTime() != null, Employee::getUpdateTime, employee.getUpdateTime())
                .set(employee.getUpdateUser() != null, Employee::getUpdateUser, employee.getUpdateUser());

        this.update( wrapper);


    }

}
